package jogoprojetopi;

import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import s3t.gameControl.system.GameSystem;
import s3t.gameElements.*;
import s3t.graphicsElements.ImageCollection;
import s3t.graphicsElements.SimpleImage;

public class ControleDoInimigo extends AIAction {

    private boolean death = false; //verificado de morte do inimigo
    private long bulletTime = 0; // tempo do tiro
    private ImageCollection bulletImages = new ImageCollection();
    private int randomMove;
    private double lastPositionX;
    private double lastPositionY;
    private double currentPositionX;
    private double currentPositionY;
    String imageKey;
    Element player = GameSystem.getInstance().getElementCollection().getElementByName("Personagem");

    //*A
    private ArrayList<Point> resultPath = new ArrayList<Point>();
    private boolean enableSearch = true;

    public void doAction(Element element) {

        imageKey = null;

        if (death)
        {
            imageKey = "morra";
        }

        //A*
        if( enableSearch && resultPath.isEmpty() )
        {
            Point sp = new Point((int)element.getX(), (int)element.getY());
            Point ep = new Point((int)player.getX(), (int)player.getY());

            resultPath = PathFinder.find( PathFinder.getElementMapPos( sp ), PathFinder.getElementMapPos( ep ), 0, 0, false );
            resultPath.remove(0);
            enableSearch = false;
        }
        else
        {
            if( resultPath.isEmpty() )
            {
                enableSearch = true;
            }
            else
            {
               if( element.getX() == (double)resultPath.get(0).x && element.getY() == (double)resultPath.get(0).y )
                {
                resultPath.remove(0);
                }
                else
                {
                    double vx  = (double)resultPath.get(0).x - (double)element.getX();
                    double vy  = (double)resultPath.get(0).y - (double)element.getY();

                    int len = (int) Math.sqrt( vx * vx + vy * vy  );
                    double dx  = vx / len;
                    double dy  = vy / len;

                    //Movimentação do Inimigo
                    //Só se movimenta caso esteja a uma distância do personagem
                    if(distancia(player, element) > 100)
                    {
                        //cima
                        if (dx == 0 && dy == -1) {
                            imageKey = "andarCima";
                            element.doMove(0, -5);
                        }
                        //direita
                        else if(dx == 1 && dy == 0) {
                            imageKey = "andarDireita";
                            element.doMove(+5, 0);
                        }
                        //baixo
                        else if(dx == 0 && dy == 1) {
                            imageKey = "andarBaixo";
                            element.doMove(0, +5);
                        }
                        //esquerda
                        else if(dx == -1 && dy == 0) {
                            imageKey = "andarEsquerda";
                            element.doMove(-5, 0);
                        }

                        //cima esquerda
                        else if(dx < 0 && dy < 0) {
                            imageKey = "andarEsquerda";
                            element.doMove(-5, -5);
                        }
                        //cima direita
                        else if(dx < 1 && dy < 0) {
                            imageKey = "andarDireita";
                            element.doMove(+5, -5);
                        }
                        //baixo esquerda
                        else if(dx < 0 && dy < 1) {
                            imageKey = "andarEsquerda";
                            element.doMove(-5, +5);
                        }
                        //baixo direita
                        else if(dx > 0 && dx < 1 && dy > 0 && dy < 1) {
                            imageKey = "andarDireita";
                            element.doMove(+5, +5);
                        }
                    }
                    

                    if (distancia(player, element) < 300)
                    {
                        try {
                            bulletImages.add("tiroInimigo", new SimpleImage("/tiro.png"));
                            bulletImages.setDefaultKey("tiroInimigo");
                            bulletImages.addAttackRectangle("tiroInimigo", new Rectangle(-3, -3, 6, 6), 0);
                        } catch (IOException ex) {
                            Logger.getLogger(ControleDoPersonagem.class.getName()).log(Level.SEVERE, null, ex);
                        }

                        if (System.currentTimeMillis() > bulletTime + 1000) {
                            bulletTime = System.currentTimeMillis();
                            Element tiro = new Element("tiroInimigo", element.getX(), element.getY(), LoadIMages.scenario);
                            tiro.setImageCollection(bulletImages);
                            tiro.setDoNotStop(true);
                            GameSystem.getInstance().getElementCollection().addElement(tiro);
                            tiro.setCollisionListener(new CollisionTiroInimigo());

                            //direção do tiro
                            double distanceX = element.getX() - player.getX();
                            double distanceY = element.getY() - player.getY();

                            //verifico se o tira é pra cima ou pra direita
                            if(distanceX < distanceY)
                            {
                                //se algum valor deles for negativo, transformo em positivo
                                if(distanceX < 0)
                                {
                                    distanceX *= -1;
                                }
                                if(distanceY < 0)
                                {
                                    distanceY *= -1;
                                }
                                //vejo qual valor está mais próximo de 0, se no eixoX então o tiro é pra cima,
                                //se no eixoY, o tiro é pra direita
                                if(distanceX < distanceY)
                                {
                                    GameSystem.getInstance().getAIEngine().setIAElement(tiro, new ControleDoTiroInimigo(Direcoes.CIMA));
                                }
                                else
                                {
                                    GameSystem.getInstance().getAIEngine().setIAElement(tiro, new ControleDoTiroInimigo(Direcoes.DIREITA));
                                }                               
                            }
                            //tiro pra baixo ou esquerda
                            else if(distanceX > distanceY)
                            {
                                //se algum valor deles for negativo, transformo em positivo
                                if(distanceX < 0)
                                {
                                    distanceX *= -1;
                                }
                                if(distanceY < 0)
                                {
                                    distanceY *= -1;
                                }
                                //vejo qual valor está mais próximo de 0, se no eixoX então o tiro é pra baixo,
                                //se no eixoY, o tiro é pra esquerda
                                if(distanceX < distanceY)
                                {
                                    GameSystem.getInstance().getAIEngine().setIAElement(tiro, new ControleDoTiroInimigo(Direcoes.BAIXO));
                                }
                                else
                                {
                                    GameSystem.getInstance().getAIEngine().setIAElement(tiro, new ControleDoTiroInimigo(Direcoes.ESQUERDA));
                                }  
                            }
                        }
                    }
                element.setImageKey(imageKey);
                }
            }
        }         

    }

    private double distancia(Element e1, Element e2) {
        return Math.sqrt(Math.pow(e1.getX() - e2.getX(), 2) + Math.pow(e1.getY() - e2.getY(), 2));
    }

    public void receiveMessage(String message) {
        if (message.equals("morra")) {
            death = true;
        }
    }
}
